package com.example.origin.resttemplate.util;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/**
 * 并发测试工具类
 *
 * @author zyt
 * @create 2018-04-27 18:56
 **/
@Slf4j
@UtilityClass
public class ConcurrentUtil {

    private static final int THREADNUM = 100;

    public void concurrenTest(Consumer<Integer> consumer, int threadNum) {
        CountDownLatch inner = new CountDownLatch(threadNum);
        CountDownLatch outer = new CountDownLatch(threadNum);
        ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
        for (int i = 0; i < threadNum; i++) {
            int finali = i;
            try {
                executorService.execute(() -> {
                    try {
                        inner.await();
                        consumer.accept(finali);
                    } catch (Exception e) {
                        log.error(e.getMessage(),e);
                    }finally {
                        outer.countDown();
                    }
                });
            }finally {
                inner.countDown();
            }
        }
        try {
            outer.await();
        } catch (InterruptedException e) {
            log.error(e.getMessage(),e);
        }finally {
            executorService.shutdown();
            try {
                boolean flag ;
                do{
                   flag = !executorService.awaitTermination(50, TimeUnit.MILLISECONDS);
                }while (flag);
            } catch (InterruptedException e) {
                log.error(e.getMessage(),e);
            }
        }
    }

    public void concurrenTest(Consumer<Integer> consumer) {
        concurrenTest(consumer, THREADNUM);
    }

}
